interface IOption {
  default: any;
  set?: boolean;
}

function createNote(type: any): any {
  if ("repository" === type) {
    return (Obj: any) => {
      const object = new Obj();
      return class Stroe {
        public namespaced: boolean = object.namespaced;
        public nameString: string = Obj.name;
        public state: any          = object.state || {};
        public actions: any        = object.actions || {};
        public getters: any        = object.getters || {};
        public mutations: any      = object.mutations || {};
      };
    };
  }
  if ("state" === type) {
    return (options: IOption) => {
      return (object: any, key: string) => {
        object[type] = {...object[type], [key]: options.default || null};
        if (options.set) {
          const setFun: any  = (state: any, value: any) => state[key] = value;
          const name: string = key.replace(/\b(\w)/g, (val: string) => val.toUpperCase());
          object.mutations = {...object.mutations, [`set${name}`]: setFun};
        }
      };
    };
  }
  return (object: any, key: any, content: any) => {
    object[type] = {...object[type], [key]: content.value};
  };
}

export const State      = createNote("state");
export const Action     = createNote("actions");
export const Getter     = createNote("getters");
export const Mutation   = createNote("mutations");
export const Repository = createNote("repository");
